package com.my.util;

import javax.servlet.*;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Enumeration;
import java.util.HashMap;

public class CharacterEncodingFilter implements Filter {

    private String encoding;
    private FilterConfig filterConfig;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        if (encoding != null) {
            request.setCharacterEncoding(encoding);
            response.setContentType("text/html; charset=" + encoding);

            // 对request包装，处理getParameter乱码问题
            chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
                @Override
                public String getParameter(String name) {
                    String value = super.getParameter(name);
                    if (value == null) {
                        return null;
                    }
                    try {
                        return new String(value.getBytes(encoding), encoding);
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public Map<String, String[]> getParameterMap() {
                    Map<String, String[]> map = super.getParameterMap();
                    if (map != null) {
                        for (String key : map.keySet()) {
                            String[] values = map.get(key);
                            for (int i = 0; i < values.length; i++) {
                                try {
                                    values[i] = new String(values[i].getBytes(encoding), encoding);
                                } catch (UnsupportedEncodingException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                        }
                    }
                    return map;
                }

                @Override
                public String[] getParameterValues(String name) {
                    String[] values = super.getParameterValues(name);
                    if (values == null) {
                        return null;
                    }
                    for (int i = 0; i < values.length; i++) {
                        try {
                            values[i] = new String(values[i].getBytes(encoding), encoding);
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    return values;
                }
            }, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    public void destroy() {
        this.encoding = null;
        this.filterConfig = null;
    }
}